#include "MessageHeader.h"
#include <chrono>
#include <sstream>
#include <iomanip>
#include <random>
#include <ctime>

namespace MessageFramework {

// ==================== 辅助函数 ====================

static int64_t getCurrentTimestampNs() {
    auto now = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<std::chrono::nanoseconds>(
        now.time_since_epoch()).count();
}

static std::string generateUUID() {
    static std::random_device rd;
    static std::mt19937_64 gen(rd());
    static std::uniform_int_distribution<uint64_t> dis;

    uint64_t high = dis(gen);
    uint64_t low = dis(gen);

    std::ostringstream oss;
    oss << std::hex << std::setfill('0')
        << std::setw(16) << high
        << std::setw(16) << low;
    return oss.str();
}

// ==================== MessageHeader 实现 ====================

std::string MessageHeader::serialize() const {
    std::ostringstream oss;
    oss << "{"
        << "\"messageId\":\"" << messageId << "\","
        << "\"messageType\":\"" << messageType << "\","
        << "\"version\":\"" << version << "\","
        << "\"publisherId\":\"" << publisherId << "\","
        << "\"consumerId\":\"" << consumerId << "\","
        << "\"targetStream\":\"" << targetStream << "\","
        << "\"replyStream\":\"" << replyStream << "\","
        << "\"timestamp\":" << timestamp << ","
        << "\"expiresAt\":" << expiresAt << ","
        << "\"signature\":\"" << signature << "\","
        << "\"encrypted\":" << (encrypted ? "true" : "false") << ","
        << "\"encryptionAlgo\":\"" << encryptionAlgo << "\","
        << "\"traceId\":\"" << traceId << "\","
        << "\"parentId\":\"" << parentId << "\","
        << "\"priority\":" << priority << ","
        << "\"contentLength\":" << contentLength << ","
        << "\"contentType\":\"" << contentType << "\""
        << "}";
    return oss.str();
}

MessageHeader MessageHeader::deserialize(const std::string& data) {
    MessageHeader header;
    // 简化实现：使用字符串解析（生产环境建议使用JSON库）
    // 这里只是示例，实际应使用jsoncpp或rapidjson

    auto extractString = [&](const std::string& key) -> std::string {
        std::string pattern = "\"" + key + "\":\"";
        size_t start = data.find(pattern);
        if (start == std::string::npos) return "";
        start += pattern.length();
        size_t end = data.find("\"", start);
        if (end == std::string::npos) return "";
        return data.substr(start, end - start);
    };

    auto extractInt64 = [&](const std::string& key) -> int64_t {
        std::string pattern = "\"" + key + "\":";
        size_t start = data.find(pattern);
        if (start == std::string::npos) return 0;
        start += pattern.length();
        size_t end = data.find_first_of(",}", start);
        if (end == std::string::npos) return 0;
        return std::stoll(data.substr(start, end - start));
    };

    auto extractInt = [&](const std::string& key) -> int {
        return static_cast<int>(extractInt64(key));
    };

    auto extractBool = [&](const std::string& key) -> bool {
        std::string pattern = "\"" + key + "\":";
        size_t start = data.find(pattern);
        if (start == std::string::npos) return false;
        start += pattern.length();
        return data.substr(start, 4) == "true";
    };

    std::strncpy(header.messageId, extractString("messageId").c_str(), sizeof(header.messageId) - 1);
    std::strncpy(header.messageType, extractString("messageType").c_str(), sizeof(header.messageType) - 1);
    std::strncpy(header.version, extractString("version").c_str(), sizeof(header.version) - 1);
    std::strncpy(header.publisherId, extractString("publisherId").c_str(), sizeof(header.publisherId) - 1);
    std::strncpy(header.consumerId, extractString("consumerId").c_str(), sizeof(header.consumerId) - 1);
    std::strncpy(header.targetStream, extractString("targetStream").c_str(), sizeof(header.targetStream) - 1);
    std::strncpy(header.replyStream, extractString("replyStream").c_str(), sizeof(header.replyStream) - 1);
    header.timestamp = extractInt64("timestamp");
    header.expiresAt = extractInt64("expiresAt");
    std::strncpy(header.signature, extractString("signature").c_str(), sizeof(header.signature) - 1);
    header.encrypted = extractBool("encrypted");
    std::strncpy(header.encryptionAlgo, extractString("encryptionAlgo").c_str(), sizeof(header.encryptionAlgo) - 1);
    std::strncpy(header.traceId, extractString("traceId").c_str(), sizeof(header.traceId) - 1);
    std::strncpy(header.parentId, extractString("parentId").c_str(), sizeof(header.parentId) - 1);
    header.priority = extractInt("priority");
    header.contentLength = extractInt("contentLength");
    std::strncpy(header.contentType, extractString("contentType").c_str(), sizeof(header.contentType) - 1);

    return header;
}

std::map<std::string, std::string> MessageHeader::toRedisFields() const {
    std::map<std::string, std::string> fields;
    fields["messageId"] = messageId;
    fields["messageType"] = messageType;
    fields["version"] = version;
    fields["publisherId"] = publisherId;
    fields["consumerId"] = consumerId;
    fields["targetStream"] = targetStream;
    fields["replyStream"] = replyStream;
    fields["timestamp"] = std::to_string(timestamp);
    fields["expiresAt"] = std::to_string(expiresAt);
    fields["signature"] = signature;
    fields["encrypted"] = encrypted ? "1" : "0";
    fields["encryptionAlgo"] = encryptionAlgo;
    fields["traceId"] = traceId;
    fields["parentId"] = parentId;
    fields["priority"] = std::to_string(priority);
    fields["contentLength"] = std::to_string(contentLength);
    fields["contentType"] = contentType;
    return fields;
}

MessageHeader MessageHeader::fromRedisFields(const std::map<std::string, std::string>& fields) {
    MessageHeader header;

    auto getString = [&](const std::string& key) -> std::string {
        auto it = fields.find(key);
        return (it != fields.end()) ? it->second : "";
    };

    auto getInt64 = [&](const std::string& key) -> int64_t {
        auto it = fields.find(key);
        return (it != fields.end()) ? std::stoll(it->second) : 0;
    };

    auto getInt = [&](const std::string& key) -> int {
        auto it = fields.find(key);
        return (it != fields.end()) ? std::stoi(it->second) : 0;
    };

    auto getBool = [&](const std::string& key) -> bool {
        auto it = fields.find(key);
        return (it != fields.end()) ? (it->second == "1" || it->second == "true") : false;
    };

    std::strncpy(header.messageId, getString("messageId").c_str(), sizeof(header.messageId) - 1);
    std::strncpy(header.messageType, getString("messageType").c_str(), sizeof(header.messageType) - 1);
    std::strncpy(header.version, getString("version").c_str(), sizeof(header.version) - 1);
    std::strncpy(header.publisherId, getString("publisherId").c_str(), sizeof(header.publisherId) - 1);
    std::strncpy(header.consumerId, getString("consumerId").c_str(), sizeof(header.consumerId) - 1);
    std::strncpy(header.targetStream, getString("targetStream").c_str(), sizeof(header.targetStream) - 1);
    std::strncpy(header.replyStream, getString("replyStream").c_str(), sizeof(header.replyStream) - 1);
    header.timestamp = getInt64("timestamp");
    header.expiresAt = getInt64("expiresAt");
    std::strncpy(header.signature, getString("signature").c_str(), sizeof(header.signature) - 1);
    header.encrypted = getBool("encrypted");
    std::strncpy(header.encryptionAlgo, getString("encryptionAlgo").c_str(), sizeof(header.encryptionAlgo) - 1);
    std::strncpy(header.traceId, getString("traceId").c_str(), sizeof(header.traceId) - 1);
    std::strncpy(header.parentId, getString("parentId").c_str(), sizeof(header.parentId) - 1);
    header.priority = getInt("priority");
    header.contentLength = getInt("contentLength");
    std::strncpy(header.contentType, getString("contentType").c_str(), sizeof(header.contentType) - 1);

    return header;
}

std::string MessageHeader::generateMessageId() {
    int64_t timestamp = getCurrentTimestampNs();
    std::ostringstream oss;
    oss << timestamp << "-" << generateUUID().substr(0, 8);
    return oss.str();
}

std::string MessageHeader::generateTraceId() {
    return generateUUID();
}

bool MessageHeader::isExpired() const {
    if (expiresAt == 0) {
        return false;  // 不过期
    }
    int64_t now = getCurrentTimestampNs();
    return now > expiresAt;
}

bool MessageHeader::validate() const {
    // 基本字段验证
    if (std::strlen(messageId) == 0) return false;
    if (std::strlen(messageType) == 0) return false;
    if (std::strlen(publisherId) == 0) return false;
    if (std::strlen(targetStream) == 0) return false;
    if (timestamp == 0) return false;
    if (contentLength < 0) return false;

    // 版本验证
    if (std::strlen(version) == 0) return false;

    // 优先级范围验证
    if (priority < 0 || priority > 9) return false;

    // 过期检查
    if (isExpired()) return false;

    return true;
}

} // namespace MessageFramework
